#include "logger.h"
#include <cstdlib>
#include <ctime>
#include <Windows.h>

std::ofstream Logger::m_error_log_file;
std::ofstream Logger::m_info_log_file;
std::ofstream Logger::m_warn_log_file;

void initLogger(const std::string &info_log_filename,
                const std::string &warn_log_filename,
                const std::string &error_log_filename)
{
    Logger::m_info_log_file.open(info_log_filename.c_str(), std::ios_base::out);
    Logger::m_warn_log_file.open(warn_log_filename.c_str(), std::ios_base::out);
    Logger::m_error_log_file.open(error_log_filename.c_str(), std::ios_base::out);
}

std::ostream &Logger::getStream(log_rank_t log_rank)
{
    return (LOG_INFO == log_rank)
               ? (m_info_log_file.is_open()
                      ? m_info_log_file
                      : std::cout)
               : (LOG_WARNING == log_rank
                      ? (m_warn_log_file.is_open()
                             ? m_warn_log_file
                             : std::cerr)
                      : ((LOG_ERROR == log_rank)
                             ? (m_error_log_file.is_open()
                                    ? m_error_log_file
                                    : std::cerr)
                             : std::cerr));
}

std::ostream &Logger::start(log_rank_t log_rank,
                            const int line,
                            const std::string &function)
{
    time_t tm;
    time(&tm);
    char time_string[100];
    strftime(time_string, 100, "%c", localtime(&tm));
    SYSTEMTIME systm;
    GetLocalTime(&systm);
#ifdef LOG_NO_INFO
    return getStream(log_rank) << std::flush;
#endif
    return getStream(log_rank) << time_string << "." << systm.wMilliseconds
                               << "--function (" << function << ")"
                               << "line " << line << ":\n"
                               << std::flush;
}

Logger::~Logger()
{
    getStream(m_log_rank) << std::endl
                          << std::flush;

    if (LOG_FATAL == m_log_rank)
    {
        m_info_log_file.close();
        m_error_log_file.close();
        m_warn_log_file.close();
        // abort();
    }
}